package com.fastjrun.eladmin.itrms.service.impl;

import com.fastjrun.eladmin.itrms.common.exception.ServiceException;
import com.fastjrun.eladmin.itrms.dao.*;
import com.fastjrun.eladmin.itrms.dto.ProjectDTO;
import com.fastjrun.eladmin.itrms.dto.ProjectQueryDTO;
import com.fastjrun.eladmin.itrms.dto.ProjectServerQueryDTO;
import com.fastjrun.eladmin.itrms.dto.ProjectSoftQueryDTO;
import com.fastjrun.eladmin.itrms.entity.*;
import com.fastjrun.eladmin.itrms.mapstruct.RmsProjectMapper;
import com.fastjrun.eladmin.itrms.mapstruct.RmsServerMapper;
import com.fastjrun.eladmin.itrms.mapstruct.RmsSoftMapper;
import com.fastjrun.eladmin.itrms.service.RmsProjectControllerService;
import com.fastjrun.eladmin.itrms.utils.PageUtils;
import com.fastjrun.eladmin.itrms.vo.ProjectVO;
import com.fastjrun.eladmin.itrms.vo.ServerVO;
import com.fastjrun.eladmin.itrms.vo.SoftVO;
import com.fastjrun.eladmin.vo.PageResult;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.SecurityUtils;
import me.zhengjie.utils.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service("rmsProjectControllerService")
public class RmsProjectControllerServiceImpl extends BaseItrmsService implements RmsProjectControllerService {
    @Resource
    RmsProjectServerDao rmsProjectServerDao;
    @Resource
    RmsProjectSoftDao rmsProjectSoftDao;

    @Resource
    RmsProjectDao rmsProjectDao;
    @Resource
    RmsServerDao rmsServerDao;
    @Resource
    RmsProjectMapper rmsProjectMapper;
    @Resource
    RmsSoftDao rmsSoftDao;
    @Resource
    RmsServerMapper rmsServerMapper;

    @Resource
    RmsSoftMapper rmsSoftMapper;

    private RmsProjectExample retrive(ProjectQueryDTO queryDTO) {
        log.debug("queryDTO={}", queryDTO);
        RmsProjectExample rmsProjectExample = new RmsProjectExample();
        return rmsProjectExample;
    }

    @Override
    public void export(HttpServletResponse response, ProjectQueryDTO queryDTO) {
        RmsProjectExample rmsProjectExample = this.retrive(queryDTO);
        List<RmsProject> all = rmsProjectDao.selectByExampleWithBLOBs(rmsProjectExample);
        List<ProjectVO> projectVOS = this.rmsProjectMapper.toVO(all);
        List<Map<String, Object>> list = Lists.newArrayList();
        for (RmsProject project : all) {
            Map<String, Object> map = Maps.newHashMap();
            map.put("项目编号", project.getProjectNo());
            map.put("项目名称", project.getProjectName());
            map.put("备注", project.getRemark());
            map.put("负责用户ID", project.getOwnerUserId());
            map.put("创建用户ID", project.getCreateUserId());
            map.put("负责用户", project.getOwnerUser());
            map.put("创建用户", project.getCreateUser());
            map.put("创建时间", project.getCreateDate());
            map.put("更新时间", project.getUpdateDate());
            list.add(map);
        }
        try {
            FileUtil.downloadExcel(list, response);
        } catch (IOException e) {
            log.warn("", e);
            throw new ServiceException(e);
        }


    }

    @Override
    public PageResult<ProjectVO> query(ProjectQueryDTO queryDTO, Pageable pageable) {

        if (pageable == null) {
            pageable = PageRequest.of(PAGE_CURRENT, PAGE_SIZE);
        }


        PageUtils.startPage(pageable);


        RmsProjectExample rmsProjectExample = this.retrive(queryDTO);
        String orderClause=this.getOrderClause(pageable);
        if(StringUtils.isNotBlank(orderClause)){
            rmsProjectExample.setOrderByClause(orderClause);
        }

        PageInfo<RmsProject> pageInfo = new PageInfo<>(rmsProjectDao.selectByExampleWithBLOBs(rmsProjectExample));
        List<ProjectVO> list = rmsProjectMapper.toVO(pageInfo.getList());

        PageResult<ProjectVO> pageResult = new PageResult<>();
        pageResult.setContent(list);
        pageResult.setTotalElements((int) pageInfo.getTotal());
        return pageResult;
    }

    @Override
    public ProjectVO detail(Long projectId) {
        RmsProject rmsProject=this.rmsProjectDao.selectByPrimaryKey(projectId);
        return rmsProjectMapper.toVO(rmsProject);
    }

    @Override
    public void create(ProjectDTO createDTO) {
        RmsProject rmsProject = this.rmsProjectMapper.toEntity(createDTO);
        rmsProject.setCreateUser(SecurityUtils.getCurrentUsername());
        rmsProject.setCreateUserId(SecurityUtils.getCurrentUserId());
        rmsProject.setOwnerUser(sysUserDao.selectByPrimaryKey(createDTO.getOwnerUserId()).getUsername());
        rmsProject.setCreateDate(new Date());
        rmsProject.setUpdateDate(new Date());
        rmsProjectDao.insert(rmsProject);

    }

    @Override
    public void update(ProjectDTO updateDTO) {
        RmsProject rmsProject = this.rmsProjectMapper.toEntity(updateDTO);
        rmsProject.setOwnerUser(sysUserDao.selectByPrimaryKey(updateDTO.getOwnerUserId()).getUsername());
        rmsProject.setUpdateDate(new Date());
        rmsProjectDao.updateByPrimaryKeySelective(rmsProject);

    }

    @Override
    public void delete(Long[] ids) {
        RmsProjectExample rmsProjectExample = new RmsProjectExample();
        rmsProjectExample.createCriteria().andIdIn(Arrays.asList(ids));
        rmsProjectDao.deleteByExample(rmsProjectExample);

    }

    @Override
    public PageResult<ServerVO> queryServer(Long projectId, ProjectServerQueryDTO queryDTO, Pageable pageable) {


        RmsProjectServerExample rmsProjectServerExample = new RmsProjectServerExample();
        rmsProjectServerExample.createCriteria().andProjectIdEqualTo(projectId);
        List<RmsProjectServer> rmsProjectServers = rmsProjectServerDao.selectByExample(rmsProjectServerExample);


        List<Long> serverIds = rmsProjectServers.parallelStream().map(RmsProjectServer::getServerId).collect(Collectors.toList());


        RmsServerExample rmsServerExample = new RmsServerExample();
        RmsServerExample.Criteria criteria = rmsServerExample.createCriteria();
        if (queryDTO != null) {
            if (queryDTO.getStatus() != null) {
                criteria.andStatusEqualTo(queryDTO.getStatus());
            }
            if (queryDTO.getAllocated() != null) {
                if (queryDTO.getAllocated()) {
                    if(CollectionUtils.isEmpty(serverIds)){
                        return new PageResult<>();
                    }else{
                        criteria.andIdIn(serverIds);
                    }
                } else {
                    if(!CollectionUtils.isEmpty(serverIds)){
                        criteria.andIdNotIn(serverIds);
                    }

                }
            }
        }


        PageInfo<RmsServer> pageInfo = new PageInfo<>(rmsServerDao.selectByExample(rmsServerExample));
        List<ServerVO> list = rmsServerMapper.toVO(pageInfo.getList());

        PageResult<ServerVO> pageResult = new PageResult<>();
        pageResult.setContent(list);
        pageResult.setTotalElements((int) pageInfo.getTotal());
        return pageResult;
    }

    @Override
    public void allocateServer(Long projectId, Long[] ids) {
        for (Long id : ids) {
            RmsProjectServer rmsProjectServer = new RmsProjectServer();
            rmsProjectServer.setProjectId(projectId);
            rmsProjectServer.setServerId(id);
            rmsProjectServerDao.insert(rmsProjectServer);
        }

    }

    @Override
    public void disAllocateServer(Long projectId, Long[] ids) {
        RmsProjectServerExample rmsProjectServerExample = new RmsProjectServerExample();
        rmsProjectServerExample.createCriteria().andProjectIdEqualTo(projectId).andServerIdIn(Arrays.asList(ids));
        rmsProjectServerDao.deleteByExample(rmsProjectServerExample);

    }

    @Override
    public PageResult<SoftVO> querySoft(Long projectId, ProjectSoftQueryDTO queryDTO, Pageable pageable) {
        RmsProjectSoftExample rmsProjectSoftExample = new RmsProjectSoftExample();
        rmsProjectSoftExample.createCriteria().andProjectIdEqualTo(projectId);
        List<RmsProjectSoft> rmsProjectSofts = rmsProjectSoftDao.selectByExample(rmsProjectSoftExample);


        List<Long> softIds = rmsProjectSofts.parallelStream().map(RmsProjectSoft::getSoftId).collect(Collectors.toList());


        RmsSoftExample rmsSoftExample = new RmsSoftExample();
        RmsSoftExample.Criteria criteria = rmsSoftExample.createCriteria();
        if (queryDTO != null) {
            if (queryDTO.getAllocated() != null) {
                if (queryDTO.getAllocated()) {
                    if(CollectionUtils.isEmpty(softIds)){
                        return new PageResult<>();
                    }else{
                        criteria.andIdIn(softIds);
                    }
                } else {
                    if(!CollectionUtils.isEmpty(softIds)){
                        criteria.andIdNotIn(softIds);
                    }

                }
            }
        }


        PageInfo<RmsSoft> pageInfo = new PageInfo<>(rmsSoftDao.selectByExampleWithBLOBs(rmsSoftExample));
        List<SoftVO> list = rmsSoftMapper.toVO(pageInfo.getList());

        PageResult<SoftVO> pageResult = new PageResult<>();
        pageResult.setContent(list);
        pageResult.setTotalElements((int) pageInfo.getTotal());
        return pageResult;
    }

    @Override
    public void allocateSoft(Long projectId, Long[] ids) {
        for (Long id : ids) {
            RmsProjectSoft rmsProjectSoft = new RmsProjectSoft();
            rmsProjectSoft.setProjectId(projectId);
            rmsProjectSoft.setSoftId(id);
            rmsProjectSoftDao.insert(rmsProjectSoft);
        }


    }

    @Override
    public void disAllocateSoft(Long projectId, Long[] ids) {
        RmsProjectSoftExample rmsProjectSoftExample = new RmsProjectSoftExample();
        rmsProjectSoftExample.createCriteria().andProjectIdEqualTo(projectId).andSoftIdIn(Arrays.asList(ids));
        rmsProjectSoftDao.deleteByExample(rmsProjectSoftExample);

    }
}
